﻿namespace RemoteTestRunner.RTRDiagnosisTests
{
    using System;
    using System.Collections;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using UnitTesting;

    /// <summary>
    /// This is a test class for TestMethodHelperTest and is intended
    /// to contain all TestMethodHelperTest Unit Tests
    /// </summary>
    [TestClass]
    public class TestMethodHelperTest
    {
        /// <summary>
        /// Gets or sets the test context which provides
        /// information about and functionality for the current test run.
        /// </summary>
        public TestContext TestContext { get; set; }

        #region Additional test attributes

        // You can use the following additional attributes as you write your tests:
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext)
        // {
        // }
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup()
        // {
        // }
        // Use TestInitialize to run code before running each test
        // [TestInitialize()]
        // public void MyTestInitialize()
        // {
        // }
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup()
        // {
        // }
        #endregion

        #region Enum tests

        /// <summary>
        /// The my enum.
        /// </summary>
        public enum MyEnum
        {
            /// <summary>
            /// The a.
            /// </summary>
            A,

            /// <summary>
            /// The b.
            /// </summary>
            B,

            /// <summary>
            /// The c.
            /// </summary>
            C
        }

        /// <summary>
        /// The enum parse internal test.
        /// </summary>
        [TestMethod]
        [DeploymentItem("RemoteTestRunner.UnitTesting.dll")]
        public void EnumParseInternalTest()
        {
            var expected = MyEnum.C;
            MyEnum actual;
            actual = TestMethodHelper.EnumParseInternal(DBNull.Value, false, MyEnum.C);
            Assert.AreEqual(expected, actual);

            expected = MyEnum.A;
            actual = TestMethodHelper.EnumParseInternal(DBNull.Value, false, default(MyEnum));
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.EnumParseInternal(" ", false, default(MyEnum));
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.EnumParseInternal(null, false, default(MyEnum));
            Assert.AreEqual(expected, actual);

            expected = MyEnum.B;
            actual = TestMethodHelper.EnumParseInternal("b", true, default(MyEnum));
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// The enum parse internal exception test.
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentException))]
        [DeploymentItem("RemoteTestRunner.UnitTesting.dll")]
        public void EnumParseInternalExceptionTest()
        {
            var expected = MyEnum.C;
            MyEnum actual;

            expected = MyEnum.A;
            actual = TestMethodHelper.EnumParseInternal("b", false, default(MyEnum));
            Assert.AreEqual(expected, actual);
        }

        #endregion

        /// <summary>
        /// The parse internal test.
        /// </summary>
        [TestMethod]
        public void ParseInternalTest()
        {
            var expected = default(bool);
            bool actual;
            actual = TestMethodHelper.ParseInternal<bool>(null);
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.ParseInternal<bool>(DBNull.Value);
            Assert.AreEqual(expected, actual);

            bool? expectedNull = null;
            bool? actualNull;
            actualNull = TestMethodHelper.ParseInternal<bool?>(null);
            Assert.AreEqual(expectedNull, actualNull);

            actualNull = TestMethodHelper.ParseInternal<bool?>(DBNull.Value);
            Assert.AreEqual(expectedNull, actualNull);
        }

        ///// <summary>
        ///// Parses the internal GUID test.
        ///// </summary>
        //[TestMethod]
        //public void ParseInternalNullableGuidTest()
        //{
        //    var expected = default(Guid?);
        //    var actual = TestMethodHelper.ParseInternal<Guid?>(null);
        //}

        /// <summary>
        /// The parse internal string test.
        /// </summary>
        [TestMethod]
        public void ParseInternalStringTest()
        {
            var expected = "abc";
            string actual;

            object testData = "abc";

            actual = TestMethodHelper.ParseInternal<string>(testData);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// The parse internal enum test.
        /// </summary>
        [TestMethod]
        public void ParseInternalEnumTest()
        {
            var expected = MyEnum.A;
            MyEnum actual;

            actual = TestMethodHelper.ParseInternal<MyEnum>("a");
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// The parse internal exception test.
        /// </summary>
        [TestMethod, ExpectedException(typeof(InvalidOperationException))]
        public void ParseInternalExceptionTest()
        {
            var expected = new ArrayList();
            ArrayList actual;

            actual = TestMethodHelper.ParseInternal<ArrayList>("abc");
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// A test for CastHelperInternal
        /// </summary>
        /// <typeparam name="T">
        /// </typeparam>
        public void CastHelperInternalTestHelper<T>()
        {
            object value = null; // TODO: Initialize to an appropriate value
            var expected = default(T); // TODO: Initialize to an appropriate value
            T actual;
            actual = TestMethodHelper.CastHelperInternal<T>(value);
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        /// The cast helper internal test.
        /// </summary>
        [TestMethod]
        public void CastHelperInternalDecimalTest()
        {
            decimal expected = 0;
            decimal actual;

            actual = TestMethodHelper.CastHelperInternal<decimal>(null);
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.CastHelperInternal<decimal>(DBNull.Value);
            Assert.AreEqual(expected, actual);

            expected = 5;
            actual = TestMethodHelper.CastHelperInternal<decimal>(5m);
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.CastHelperInternal<decimal>("5");
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.CastHelperInternal<decimal>("5.0");
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void CastHelperInternalStringToGuidTest()
        {
            var actual = "40816fd8-7373-dd11-96c2-00142273ff70";
            Guid? expected = new Guid(actual);

            var actualGuid = TestMethodHelper.CastHelperInternal<Guid?>(actual);
            Assert.AreEqual(expected, actualGuid);
        }

        [TestMethod]
        public void CastHelperInternalGuidToGuidTest()
        {
            Guid? actual = new Guid("40816fd8-7373-dd11-96c2-00142273ff70");
            var expected = new Guid("40816fd8-7373-dd11-96c2-00142273ff70");

            var actualGuid = TestMethodHelper.CastHelperInternal<Guid>(actual);
            Assert.AreEqual(expected, actualGuid);
        }

        /// <summary>
        /// The cast helper internal nullable test.
        /// </summary>
        [TestMethod]
        public void CastHelperInternalNullableTest()
        {
            decimal? expected = null;
            decimal? actual;

            actual = TestMethodHelper.CastHelperInternal<decimal?>(null);
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.CastHelperInternal<decimal?>(DBNull.Value);
            Assert.AreEqual(expected, actual);

            expected = 5;
            actual = TestMethodHelper.CastHelperInternal<decimal?>(5m);
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.CastHelperInternal<decimal?>("5");
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.CastHelperInternal<decimal?>("5.0");
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// The field value internal test.
        /// </summary>
        [TestMethod]
        public void FieldValueInternalTest()
        {
            decimal expected = 0;
            decimal actual;

            actual = TestMethodHelper.FieldValueInternal<decimal>(null);
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.FieldValueInternal<decimal>(DBNull.Value);
            Assert.AreEqual(expected, actual);

            expected = 5;
            actual = TestMethodHelper.FieldValueInternal<decimal>(5m);
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.FieldValueInternal<decimal>("5");
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.FieldValueInternal<decimal>("5.0");
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// The field value internal nullable test.
        /// </summary>
        [TestMethod]
        public void FieldValueInternalNullableTest()
        {
            decimal? expected = null;
            decimal? actual;

            actual = TestMethodHelper.FieldValueInternal<decimal?>(null);
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.FieldValueInternal<decimal?>(DBNull.Value);
            Assert.AreEqual(expected, actual);

            expected = 5;
            actual = TestMethodHelper.FieldValueInternal<decimal?>(5m);
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.FieldValueInternal<decimal?>("5");
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.FieldValueInternal<decimal?>("5.0");
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// The field value internal nullable double test.
        /// </summary>
        [TestMethod]
        public void FieldValueInternalNullableDoubleTest()
        {
            double? expected = null;
            double? actual;

            actual = TestMethodHelper.FieldValueInternal<double?>(null);
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.FieldValueInternal<double?>(DBNull.Value);
            Assert.AreEqual(expected, actual);

            expected = 5;
            actual = TestMethodHelper.FieldValueInternal<double?>(5d);
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.FieldValueInternal<double?>("5");
            Assert.AreEqual(expected, actual);

            actual = TestMethodHelper.FieldValueInternal<double?>("5.0");
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Fields the value internal date time test.
        /// </summary>
        [TestMethod]
        public void FieldValueInternalDateTimeTest()
        {
            var expected = default(DateTime);
            var actual = TestMethodHelper.FieldValueInternal<DateTime>(null);
            Assert.AreEqual(expected, actual);

            expected = new DateTime(2009, 1, 1, 11, 1, 33);
            actual = TestMethodHelper.FieldValueInternal<DateTime>("1/1/2009 11:01:33");
            Assert.AreEqual(expected, actual);

            expected = default(DateTime);
            actual = TestMethodHelper.FieldValueInternal<DateTime>("1/1/0001 12:00 AM");
            Assert.AreEqual(expected, actual);

            expected = DateTime.MinValue;
            actual = TestMethodHelper.FieldValueInternal<DateTime>("1/1/0001 12:00 AM");
            Assert.AreEqual(expected, actual);

            expected = new DateTime(1, 1, 1, 1, 0, 0);
            actual = TestMethodHelper.FieldValueInternal<DateTime>("1/1/0001 1:00 AM");
            Assert.AreEqual(expected, actual);
        }
    }
}